
# Tested only on Linux!!!
# Images are required (see MyListCtrl._createImages())
# No more hand holding!

import sys, os, stat,shutil
import wx
import wx.lib.mixins.listctrl as listmix
import wx.lib.filebrowsebutton as filebrowsebutton
import xml.etree.ElementTree as xml

class MyListCtrl(wx.ListCtrl, listmix.ColumnSorterMixin):
    def __init__(self, parent, id_, pos, size, style):
        wx.ListCtrl.__init__(self, parent, id_, pos=pos, size=(1200,600), style=style)
        self.log = sys.stdout #XXX
	self.imageMap = {}
        self._createImages()
        self._createColumns()
        self.itemDataMap = {}
        self.path = sys.prefix
        
        listmix.ColumnSorterMixin.__init__(self, 3)
        # Events
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self)
        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self)
        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
        # for wxMSW #???
        self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
        # for wxGTK #???
        self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)

    def GetListCtrl(self):
        """ Dependancy: Used by the ColumnSorterMixin"""
        return self

    def OnRightDown(self, event):
        """ Select the current item"""
        x, y = event.GetX(), event.GetY()
        
        item, flags = self.HitTest((x, y))
        if item != wx.NOT_FOUND and flags & wx.LIST_HITTEST_ONITEM:
            self.Select(item)
        event.Skip()

    def OnItemSelected(self, event):
        self.currentItem = event.m_itemIndex
       
        event.Skip()

    def OnColClick(self, event):
        """ Sort the current column. Psst: we let ColumnSorterMixin handle this! :-P """
        
        event.Skip()

    def OnRightClick(self, event):
        #self.log.write("OnRightClick \"%s\"\n" % self.GetItemText(self.currentItem))

        # Only do this part the first time so the events are only bound once.
        if not hasattr(self, "popupID1"):
            self.popupID1 = wx.NewId()
            self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
            
        #
        # Create a menu and add some commands.
        menu = wx.Menu()
        menu.Append(self.popupID1, "Replace Selected")
        
        #
        # Now show the menu.  If an item is selected then its handler
        # will be called before PopupMenu returns.
        self.PopupMenu(menu)
        menu.Destroy()

    

    def OnPopupOne(self, event):
        filename1 = "InsertDVD.mkv"
        selfirst = self.GetFirstSelected()
        lst = [selfirst]
    
        for x in range(self.GetSelectedItemCount()):
            selnext = self.GetNextSelected(selfirst)
            #filename2 =  self.path + '/' + self.GetItemText(selfirst)
            filename2 = self.GetItemText(selfirst)
            shutil.copy(filename1,filename2)
            selfirst = selnext
        
	self.DeleteAllItems()        
        path = self.path      
	self.showDirectory(self.path,"True")
      #[self.DeleteItem(x) for x in lst[::-1]]
    
   
    def _getColumnText(self, index, col):
        item = self.GetItem(index, col)
        return item.GetText()
    
    def _createImages(self):
        """ Init: Create a wx.ImageList and populate with images"""
        self.il = wx.ImageList(16,16)
        self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
        imfolder = os.path.join(os.getcwd(), 'Bitmaps')
        #self.log.write('Loading Images:\n')
        idx = 0
        for name in os.listdir(imfolder):
            path = os.path.join(imfolder, name)
        #self.log.write(' -- %s, %s\n'%(path, name))
            self.il.Add(wx.BitmapFromImage(wx.Image(path)))
            self.imageMap[name.split('.')[0]] = idx
            idx += 1
        #self.log.write('imageMap.keys -> %s\n'%(self.imageMap.keys()))
    
    def _createColumns(self):
        """ Init: Create and size the columns """
        self.InsertColumn(0, "Name", wx.LIST_FORMAT_LEFT)
        self.InsertColumn(1, "Type", wx.LIST_FORMAT_LEFT)
        self.InsertColumn(2, "Bytes", wx.LIST_FORMAT_LEFT)
        self.SetColumnWidth(0, 200)
        self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
        self.SetColumnWidth(2, wx.LIST_AUTOSIZE)  

    def showDirectory(self, folder,tState):
        """ Clear and load the ListCtrl from file names in `folder`"""
        try:
            files = os.listdir(folder)
        except Exception:
            
            return
        else:
            self.DeleteAllItems()
            self.path = folder 
       
        #Future Add config file with valid extensions
        #set1 = set(['AVI','MKV','MPG','MOV','ISO'])        
	
     	    
      
	_itemMap = {}
        for idx, name in enumerate(files):
           path = os.path.join(folder, name)
           self.path = folder     
           if path.upper().endswith((".AVI",".VOB",".MKV",".MPG",".FLV",".MP4","MOV","WMV")):
              try:
                fstat = os.lstat(path)
                mode = fstat.st_mode
                size = fstat.st_size
              except Exception:
                continue
              if stat.S_ISDIR(mode):
                iconname = 'folder'
              elif stat.S_ISLNK(mode):
                iconname = 'link'
              else:
                iconname = 'file'
              kind = iconname.title()
              imageIdx = self.imageMap[iconname]
              index = self.InsertImageStringItem(idx, path, imageIdx)
              self.SetStringItem(index, 1, kind)
              self.SetStringItem(index, 2, str(size))
              self.SetItemData(index, idx) # required for sorter mixin!
              if tState: 
                self.Select(index)
              else:
                continue
            #
            # load up the _itemMap as we go.
              _itemMap[idx] = (path, kind, size)
        #
        # Now resize the columns.
        self.SetColumnWidth(0, wx.LIST_AUTOSIZE)
        self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
        self.SetColumnWidth(2, wx.LIST_AUTOSIZE)
        #
        # Reset self.itemDataMap for sorter mixin to function properly.
        self.itemDataMap = _itemMap


class AppFrame(wx.Frame):
    def __init__(self, parent=None, title='Offline File Replacer', size= (-1,-1)):
        wx.Frame.__init__(self, parent, title=title, size=size)
        panel = wx.Panel(self, -1)
        
        REPORTVIEWID = wx.NewId()
        LISTVIEWID = wx.NewId()
        LISTSTYLE = \
            wx.LC_REPORT \
            |wx.BORDER_SUNKEN \
            |wx.LC_SORT_ASCENDING \
            |wx.LC_VRULES \
            |wx.LC_EDIT_LABELS \
            #| wx.LC_SINGLE_SEL \
            #|wx.LC_HRULES \
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        #
        bb = self.browseButton = filebrowsebutton.DirBrowseButton(
            panel, -1, pos=(0,170),startDirectory = "/media/WDDrive/Test XBMC Media/TV Series", changeCallback=self.browseButtonCallback)
 	
	
        
	vbox.Add(bb, 0, wx.EXPAND)
	        
        self.listWidget = MyListCtrl(panel, wx.NewId(), pos=(100,100), size=(800,600), style=LISTSTYLE)
	self.listWidget.Centre()
        
	vbox.Add(self.listWidget, 1,-1)
        
        #
        self.reportviewButtonCallback(None)
        self.cb1 = wx.CheckBox(panel, -1, 'Toggle All',(180,850))
	self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, self.cb1)
        self.cb1.SetValue(True)
        self.button1 = wx.Button(panel, id=-1, label='Replace',pos=(1080,850), size=(175, 44))
        self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,id= -1)
        self.button2 = wx.Button(panel, id=-1, label='Quit',pos=(800,850), size=(175, 44))
        self.button2.Bind(wx.EVT_BUTTON, self.OnButton2Button,id= -1)        
	panel.SetSizer(vbox)
    	self.CheckConfig()
	#self.LoadConfig()
    def EvtCheckBox(self,event):
        self.listWidget.showDirectory(self.listWidget.path,self.cb1.IsChecked())
    def OnButton1Button(self, event): 
        self.listWidget.OnPopupOne(self)
    def OnButton2Button(self, event): 
        self.Close()     
    def CheckConfig(self):
	if not os.path.exists("settings.xml"):
            root = xml.Element('root')
	    Ext = xml.SubElement(root,'Ext')
	    File2Use = xml.SubElement(root,'File2Use')
	    #Create a child element
	    xml.SubElement(Ext,'".MKV"')
	    xml.SubElement(Ext,'".FLV"')
	    xml.SubElement(Ext,'".AVI"')
	    xml.SubElement(Ext,'".MOV"')
	    xml.SubElement(Ext,'".MP4"')
	    xml.SubElement(Ext,'".MPG"')
	    xml.SubElement(Ext,'".WMV"')
	    xml.SubElement(File2Use,'"InsertDVD.mkv"')
	    #Create File
	    cfg = open("settings.xml", 'w')
	    xml.ElementTree(root).write(cfg)
	    cfg.close()    
    
    def listviewButtonCallback(self, event=None):
        w = self.listWidget
        w.ClearAll()
        w.SetSingleStyle(style=wx.LC_LIST)
        w._createColumns()
        w.showDirectory(w.path,"True")
        
    def reportviewButtonCallback(self, event=None):
        w = self.listWidget
        w.ClearAll()
        w.SetSingleStyle(style=wx.LC_REPORT)
        w._createColumns()
        w.showDirectory(w.path,"True")
                
    def browseButtonCallback(self, *args):
	path = args[0].GetString()
        self.listWidget.showDirectory(path,self.cb1.IsChecked())
    
    def ButtonCallback(self, *args):
        path = args[0].GetString()
        

if __name__ == '__main__':
    app = wx.App(False)
    frame = AppFrame()
    frame.SetSize(wx.Size(1280,960))
    frame.Show(True)
    app.MainLoop()
    

